package com.lagou.edu.factory;

import com.lagou.edu.annotation.Autowired;
import com.lagou.edu.annotation.Service;
import com.lagou.edu.utils.TransactionManager;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.SQLException;

/**
 * @author 应癫
 * <p>
 * 代理对象工厂：生成代理对象的
 */
@Service
public class ProxyFactory {

    @Autowired
    private TransactionManager transactionManager;

    /**
     * Jdk动态代理
     *
     * @param obj 委托对象
     * @return 代理对象
     */
    public Object getJdkProxy(Object obj) {
        return Proxy
                .newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),
                        (proxy, method, args) -> {
                            Object result = null;
                            return transaction(obj, method, args);
                        });
    }


    /**
     * 使用cglib动态代理生成代理对象
     *
     * @param obj 委托对象
     * @return
     */
    public Object getCglibProxy(Object obj) {
        return Enhancer
                .create(obj.getClass(), (MethodInterceptor) (o, method, objects, methodProxy) -> {
                    Object result;
                    return transaction(obj, method, objects);
                });
    }

    private Object transaction(Object obj, Method method, Object[] args)
            throws SQLException, IllegalAccessException, InvocationTargetException {
        Object result;
        try {
            transactionManager.beginTransaction();
            result = method.invoke(obj, args);
            transactionManager.commit();
        } catch (Exception e) {
            e.printStackTrace();
            transactionManager.rollback();
            throw e;
        }
        return result;
    }
}
